// **********************************************************************
//  
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>
//  
// ************************************************************************

var Jabber = {
  conexion: null,

  suscripcion_pendiente : "",

  callback_estado_conexion: function (status) {
    if (status === Strophe.Status.CONNECTING){
      Jabber.callback_conectando();
    } else if (status === Strophe.Status.AUTHENTICATING){
      Jabber.callback_autentificando();
    } else if (status === Strophe.Status.CONNECTED) {
      Jabber.callback_conectado();
    } else if (status === Strophe.Status.DISCONNECTING){
      Jabber.callback_desconectando();
    } else if (status === Strophe.Status.DISCONNECTED) {
      Jabber.callback_desconectado();
    } else if (status === Strophe.Status.AUTHFAIL) {
      Jabber.callback_error_autentificacion();
    } else if (status === Strophe.Status.CONNFAIL) {
      Jabber.callback_error_conexion();
    } else{
      Jabber.callback_error_desconocido();
    }
  },

  conectar: function (credenciales){
    Jabber.conexion = new Strophe.Connection('http://bosh.metajack.im:5280/xmpp-httpbind');
    Jabber.conexion.connect(credenciales.jid, credenciales.password, Jabber.callback_estado_conexion, 10, 10);
  },

  desconectar: function (){
    Jabber.conexion.disconnect('Desconectado');
    //TODO los eventos que habria que meter
  },

  //las 5 fases normales de una conexion XMPP
  callback_conectando: function (){
    $(document).trigger('conectando');
    return true;
  },

  callback_autentificando: function(){
    $(document).trigger('autentificando');
    return true;
  },

  callback_conectado: function(){
    //las stanzas estandar de mensajes privados son <message [...] type = 'chat'>
    $(document).trigger('conectado');

    Jabber.conexion.addHandler(Jabber.callback_actualizar_presencia, null, "presence");
    Jabber.conexion.addHandler(Jabber.callback_modificacion_roster, "jabber:iq:roster", "iq", "set");
    Jabber.conexion.addHandler(Jabber.callback_nuevo_mensaje, null, "message", "chat");
    var iq = $iq({type: 'get'}).c('query', {xmlns: 'jabber:iq:roster'});
    Jabber.conexion.sendIQ(iq, Jabber.callback_recibir_roster);
    //Jabber.conexion.sendIQ(iq, Jabber.callback_recibir_roster);
    //Jabber.conexion.sendIQ(iq, Jabber.callback_recibir_roster);
    ///Jabber.conexion.sendIQ(iq, Jabber.callback_recibir_roster);
    //Jabber.conexion.sendIQ(iq, Jabber.callback_recibir_roster);
    return true;
  },

  callback_desconectando: function(){
    $(document).trigger('desconectando');
    return true;
  },

  callback_desconectado: function(){
    $(document).trigger('desconectado');
    return true;
  },

  callback_error_conexion: function(){
    $(document).trigger('error_conexion');
    return true;
  },

  callback_error_autentificacion: function(){
    $(document).trigger('error_autentificacion');
    return true;
  },

  callback_error_desconectado: function(){
    $(document).trigger('error_desconocido');
    return true;
  },

  agregar_contacto: function(datos){
    //añadir el contacto al roster
    Jabber.conexion.gestion_roster.agregar_contacto(datos.jid, datos.name);
    //Jabber.conexion.sendIQ($iq({type: "set"}).c("query", {xmlns: "jabber:iq:roster"}).c("item", datos));
  },

  agregar_suscripcion: function(jid){
    //enviar la peticion de presencia
    Jabber.conexion.gestion_roster.suscribir(jid);
    //Jabber.conexion.send($pres({to: jid, type: "subscribe"}));
    //alert($pres({to: jid, type: "subscribe"}));
  },

  eliminar_contacto: function (jid){
    Jabber.conexion.gestion_roster.eliminar_contacto(jid);
    //Jabber.conexion.sendIQ($iq({type: "set"}).c("query", {xmlns: "jabber:iq:roster"}).c("item", {jid: jid, subscription: "remove"}));
  },

  eliminar_suscripcion: function(jid){
    Jabber.conexion.gestion_roster.cancelar_tu_suscripcion(jid);
    //Jabber.conexion.gestion_roster.cancelar_tu_suscripcion(jid);
    //Jabber.conexion.gestion_roster.eliminar_contacto(jid);
    //Jabber.conexion.sendIQ($iq({type: "set"}).c("query", {xmlns: "jabber:iq:roster"}).c("item", {jid: jid, subscription: "remove"}));
    //alert($iq({type: "set"}).c("query", {xmlns: "jabber:iq:roster"}).c("item", {jid: jid, subscription: "remove"}));
  },

  bloquear_contacto: function(jid){
    Jabber.conexion.gestion_roster.cancelar_su_suscripcion(jid);
    //Jabber.conexion.send($pres({to: jid, type: "unsubscribed"}));
  },


  enviar_mensaje: function (jid, mensaje, state){
    var xml = $msg({to: jid,"type": "chat"});
    if (mensaje.length > 0) {
      xml.c('body').t(mensaje).up();
    }
    xml.c(state, {xmlns: "http://jabber.org/protocol/chatstates"});
    Jabber.conexion.send(xml);
  },

  callback_recibir_roster: function (iq) {
    $(iq).find('item').each(function () {
      var jid = $(this).attr('jid');
      var name = $(this).attr('name') || jid;
      $(document).trigger('insertar_contacto_roster', {jid: jid, nombre: name});
    });
    Jabber.conexion.send($pres());
    return true;
  },

  /* http://tools.ietf.org/html/rfc3921
   * 2.2.1.  Types of Presence
   o  unavailable -- Signals that the entity is no longer available for communication.
   o  subscribe   -- The sender wishes to subscribe to the recipient's presence.
   o  hay_mas     -- Pero ahora no tengo ganas.
   *
   *  2.2.2.1 Show
   o  away -- The entity or resource is temporarily away.
   o  chat -- The entity or resource is actively interested in chatting.
   o  dnd  -- The entity or resource is busy (dnd = "Do Not Disturb").
   o  xa   -- The entity or resource is away for an extended period (xa = "eXtended Away").
   If no <show/> element is provided, the entity is assumed to be online
   and available.
   */
  callback_actualizar_presencia: function (presencia) {

    var ptype = $(presencia).attr('type');
    var from = $(presencia).attr('from');
    var jid_id = html_id(from);
    var str_presencia ='offline';
    var show = $(presencia).find("show").text();
    if (ptype === 'subscribe') {
      //TODO esto esta muy feo

      Jabber.suscription_pendiente = Strophe.getBareJidFromJid(from);
      $('#jid_pendiente_aprobacion').text(Strophe.getBareJidFromJid(from));
      //alert(from + "puntero: " + peticion);
      //alert(from + "puntero: " + Jabber.suscription_pendiente);
      $('#dialogo_aprobar_presencia').dialog('open');
    } else if (ptype !== 'error') {
      if (ptype === 'unavailable') {
	str_presencia = 'offline';
      } else {
	//alert(presencia.text());
	//var show = $(presencia).find("show").text();
	//alert(from);
	if (show==="chat" || show === "") {
	  str_presencia = 'online';
	} else if (show === "away") {
	  str_presencia = 'away';
	} else if (show === "xa") {
	    str_presencia = 'away';
	} else if (show === "dnd") {
	    str_presencia = 'away';
	} else{
	  //TODO <show /> erroneo -> ¿y yo que le hago?
	}
      }
      $(document).trigger('actualizar_presencia', {jid: from, presencia: str_presencia});
      //alert(from);
      //alert(ptype);
      //alert(show);
      //alert(str_presencia);
    } else {
      //TODO Hay mas stanzas
    }
    //si la presencia cambia es posible que haya que cambiar su direccion
    var jid_id = html_id(from);
    $('#chat_' + jid_id).data('jid', Strophe.getBareJidFromJid(from));

    return true;
  },

  callback_modificacion_roster: function (iq) {
    $(iq).find('item').each(function () {
      var sub = $(this).attr('subscription');
      var jid = $(this).attr('jid');
      var name = $(this).attr('name') || jid;
      var jid_id = html_id(jid);
      if (sub === 'remove') {
	$(document).trigger('eliminar_contacto', jid);
      } else {
	$(document).trigger('insertar_contacto_roster',{jid: jid, nombre: name});
      }
    });

    return true;
  },

  callback_nuevo_mensaje: function (message) {
    var full_jid = $(message).attr('from');
    var jid = Strophe.getBareJidFromJid(full_jid);
    //var jid_node Strophe.getNodeFromJid(jid);
    var jid_id = html_id(jid);
    var mensaje = $(message).find('body')
    if (mensaje.length > 0){
      var cuerpo = mensaje.text();
      $(document).trigger('nuevo_mensaje', {jid: jid, nombre: jid, mensaje: cuerpo});
    }

    //$('#pizarra_chat').tabs('select', '#chat_' + jid_id);

    //TODO focus en el input, hay que ver ocurre cuando la propia pestaña no tiene focus
    //$('#chat_' + jid_id + ' input').focus();

    //TODO
    //esta forma de ahcer focus es un parchazo, tambien hay que ver como
    //hacer que el focus pase directamente al input cuando se cambia la pestaña

    if ($(message).find('composing').length > 0) {
      //$('#chat_' + jid_id + ' .ventana_chat').append( "<div class='evento'>" + Strophe.getNodeFromJid(jid) + " esta escribiendo...</div>");
      //scroll_chat(jid);
    }

    //$('#chat_' + jid_id + ' .mensaje_chat:last .cuerpo_mensaje').append(cuerpo);
    //scroll_chat(jid);
    return true;
  },
};
